package com.mars.boss.weixin.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.mars.boss.weixin.constant.RedisKeyConst;
import com.mars.boss.weixin.entity.WeixinMenu;
import com.mars.boss.weixin.exception.WeixinMenuBizException;
import com.mars.boss.weixin.mapper.WeixinMenuMapper;
import com.mars.boss.weixin.service.WeixinMenuService;
import com.mars.boss.weixin.wx.model.Menu;
import com.mars.common.exception.BizException;
import com.mars.component.redis.JedisClient;
import com.mars.service.support.BaseService;

@Service
public class WeixinMenuServiceImpl extends BaseService<WeixinMenu, Long> implements WeixinMenuService {
	
	@Autowired
	private WeixinMenuMapper mapper ;

	@Autowired
	private JedisClient jedisClient;
	
	@Override
	public int insert(WeixinMenu entity) throws WeixinMenuBizException {
		entity.setEventKey("KEY_" + System.currentTimeMillis());
		int insert = super.insert(entity) ;
		clearCache() ;
		return insert;
	}
	
	@Override
	public int deleteByIds(String ids) throws BizException {
		deletes(Long.parseLong(ids));
		clearCache() ;
		return 0;
	}
	
	private void deletes(Long id) {
		List<WeixinMenu> children = this.mapper.getMenuByParentId(id) ;
		if(null != children) {
			for (WeixinMenu WeixinMenu : children) {
				deletes(WeixinMenu.getId());
			}
		}
		super.delete(id) ;
	}
	
	@Override
	public int update(WeixinMenu entity) throws WeixinMenuBizException {
		if(entity.getId() == entity.getParentId()) {
			throw WeixinMenuBizException.NOT_RELATED_SELF ;
		}
		int update = super.update(entity);
		
		clearCache() ;
		return update;
	}
	
	@Override
	public List<WeixinMenu> getMenuCategory() throws WeixinMenuBizException {
		String weixinMenus = jedisClient.get(RedisKeyConst.WX_MENU_CATEGORY) ;
		if(null != weixinMenus && !weixinMenus.isEmpty()) {
			return JSON.parseArray(weixinMenus, WeixinMenu.class) ;
		} else {
			List<WeixinMenu> list = this.mapper.getMenuCategory() ;
			this.jedisClient.set(RedisKeyConst.WX_MENU_CATEGORY, JSON.toJSONString(list));
			return list ;
		}
	}

	@Override
	public List<WeixinMenu> getMenuByParentId(Long id) {
		String WeixinMenus = jedisClient.getHash(RedisKeyConst.WX_MENU_CATEGORY_TREE, RedisKeyConst.WX_MENU_CATEGORY_TREE + ":" + id) ;
		if(null != WeixinMenus) {
			return JSON.parseArray(WeixinMenus, WeixinMenu.class) ;
		} else {
			List<WeixinMenu> list = new ArrayList<WeixinMenu>() ;
			List<WeixinMenu> WeixinMenuByCategory = this.mapper.getMenuByParentId(id) ;
			for (WeixinMenu WeixinMenu : WeixinMenuByCategory) {
				list.add(recursiveMenu(WeixinMenu)) ;
			}
			this.jedisClient.setHash(RedisKeyConst.WX_MENU_CATEGORY_TREE, RedisKeyConst.WX_MENU_CATEGORY_TREE + ":" + id, JSON.toJSONString(list));
			return list ;
		}
	}
	
	@Override
	public List<WeixinMenu> getAllMenus() {
		String weixinMenus = jedisClient.get(RedisKeyConst.WX_MENU_ALL) ;
		if(null != weixinMenus && !weixinMenus.isEmpty()) {
			return JSON.parseArray(weixinMenus, WeixinMenu.class) ;
		} else {
			List<WeixinMenu> list = new ArrayList<WeixinMenu>() ;
			
			List<WeixinMenu> WeixinMenuCategory = this.getMenuCategory() ;
			for (WeixinMenu weixinMenu : WeixinMenuCategory) {
				list.add(recursiveMenu(weixinMenu)) ;
			}
			this.jedisClient.set(RedisKeyConst.WX_MENU_ALL, JSON.toJSONString(list));
			return list ;
		}
	}
	
	public WeixinMenu recursiveMenu(WeixinMenu menu) {
		menu.setState("open");
		List<WeixinMenu> childs = this.mapper.getMenuByParentId(menu.getId()) ;
		if(null != childs && childs.size() > 0) {
			List<WeixinMenu> children = new ArrayList<WeixinMenu>() ;
			for (WeixinMenu m : childs) {
				children.add(recursiveMenu(m)) ;
			}
			menu.setChildren(children);
		}
		return menu ;
	}

	
	/**
	 * 清除缓存
	 */
	public boolean clearCache() {
		this.jedisClient.del(RedisKeyConst.WX_MENU_ALL);
		this.jedisClient.del(RedisKeyConst.WX_MENU_CATEGORY);
		this.jedisClient.del(RedisKeyConst.WX_MENU_CATEGORY_TREE);
		return true ;
	}

	@Override
	public List<Menu> getAllMenusToWeixin() {
		List<Menu> list = new ArrayList<Menu>() ;
		
		List<WeixinMenu> WeixinMenuCategory = this.getMenuCategory() ;
		for (WeixinMenu weixinMenu : WeixinMenuCategory) {
			list.add(recursiveWeixinMenu(weixinMenu)) ;
		}
		return list ;
	}
	
	public Menu recursiveWeixinMenu(WeixinMenu menu) {
		Menu wxMenu = new Menu() ;
		wxMenu.setName(menu.getName());
		wxMenu.setKey(menu.getEventKey());
		wxMenu.setType(menu.getEventType());
		wxMenu.setUrl(menu.getUrl());
		
		List<WeixinMenu> childs = this.mapper.getMenuByParentId(menu.getId()) ;
		if(null != childs && childs.size() > 0) {
			List<Menu> sub_menus = new ArrayList<Menu>() ;
			for (WeixinMenu m : childs) {
				Menu wxm = new Menu() ;
				wxm.setName(m.getName());
				wxm.setKey(m.getEventKey());
				wxm.setType(m.getEventType());
				wxm.setUrl(m.getUrl());
				
				sub_menus.add(wxm) ;
				recursiveWeixinMenu(m) ;
			}
			wxMenu.setSub_button(sub_menus);
		}
		return wxMenu ;
	}

	@Override
	public WeixinMenu getMenuByKey(String key) {
		return this.mapper.getMenuByKey(key);
	}

	
}
